package com.product.magina.wechatserver.service.impl;

import cn.hutool.core.util.XmlUtil;
import com.google.common.collect.Maps;
import com.magina.common.exception.BusinessException;
import com.product.magina.wechatserver.constant.ProjectConst;
import com.product.magina.wechatserver.dao.DsmtCustomerDao;
import com.product.magina.wechatserver.dao.DsmtPublicWechatDao;
import com.product.magina.wechatserver.entity.DsmtCustomer;
import com.product.magina.wechatserver.entity.DsmtPublicWechat;
import com.product.magina.wechatserver.entity.WeiXinUser;
import com.product.magina.wechatserver.service.DsmtDistributionPlanService;
import com.product.magina.wechatserver.service.DsmtSMSConnectiontService;
import com.product.magina.wechatserver.service.WechatService;
import com.product.magina.wechatserver.sms.SmsClientSend;
import com.product.magina.wechatserver.utils.RandomUtil;
import com.product.magina.wechatserver.utils.WeiXinUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.w3c.dom.Document;

import javax.xml.xpath.XPathConstants;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Transactional
@Service
@Slf4j
public class DsmtSMSConnectiontServiceImpl implements DsmtSMSConnectiontService {


    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private WechatService wechatService;

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @Autowired
    private DsmtCustomerDao dsmtCustomerDao;

    @Autowired
    private DsmtPublicWechatDao dsmtPublicWechatDao;

    @Autowired
    private DsmtDistributionPlanService dsmtDistributionPlanService;

    @Value(value = "${smsserver.smsurl}")
    private String smsUrl;

    @Value(value="${smsserver.smsuserid}")
    private String smsUserId;

    @Value(value="${smsserver.smspassword}")
    private String smsPassword;

    @Value(value="${smsserver.smsaccount}")
    private String smsAccount;

    @Value(value="${wechat.projectappid}")
    private String projectAppId;

    @Value(value="${wechat.projectappsecret}")
    private String projectAppsecret;

    @Value(value = "${globalbutton.check_customer_phone_stauts}")
    private String checkCustomerPhoneStauts;

    @Override
    public Object getSMSVerificationCode(String openId, String phone) throws BusinessException {
        //校验phone
        if (ProjectConst.CHECK_CUSTOMER_PHONE_STAUTS_CLOSEING.equals(checkCustomerPhoneStauts)) {
            List<DsmtCustomer> customerList = dsmtCustomerDao.selectByPhone(phone);
            if (CollectionUtils.isEmpty(customerList)) {
                throw new BusinessException("输入手机号码尚未录入系统!");
            }
        }
        //校验opendId
        Object redisData = redisTemplate.opsForHash().values(openId +"_" +phone );
        if(!ObjectUtils.isEmpty(redisData)){
            throw new BusinessException("上次的验证码还未到期!");
        }
        String verifcationCode = RandomUtil.getRandom(6);
        //todo
        String content = "验证码:" + verifcationCode +",请尽快输入,60秒后后过期.【Magina】";
        log.info(content);
        String send = SmsClientSend.sendSms(smsUrl, smsUserId, smsAccount, smsPassword, phone, content);
        log.info(send);
        Document document = XmlUtil.readXML(send);
        Object value = XmlUtil.getByXPath("//returnsms/returnstatus", document, XPathConstants.STRING);
        log.info("send_result:"+value.toString());
        if(!value.toString().equals("Success")){
            throw new BusinessException("发送短信失败!");
        }
        //redis设置此次验证码60s
        Map map = Maps.newConcurrentMap();
        map.put("code",verifcationCode);
        map.put("phone",phone);
        redisTemplate.opsForHash().putAll(openId +"_" +phone,map);
        redisTemplate.expire(openId +"_" +phone,60,TimeUnit.SECONDS);
        log.info("========================success end getSMSVerificationCode!");
        return verifcationCode;
    }



    @Override
    public Map loginByVerificationCode(String openId, String verificationCode,String phone) throws BusinessException {
        Map map = Maps.newConcurrentMap();
        //校验opendId
        Map<Object, Object> redisData = redisTemplate.opsForHash().entries( openId +"_" +phone );
        if(ObjectUtils.isEmpty(redisData)){
            throw new BusinessException("验证码已过期,请重新获取!");
        }
        String redisCode = redisData.get("code").toString();
        if (!verificationCode.equals(redisCode)) {
            throw new BusinessException("输入验证码不匹配!");
        }
        List<DsmtCustomer> customerList = dsmtCustomerDao.selectByPhone(phone);
        if (CollectionUtils.isEmpty(customerList) ) {
            if(ProjectConst.CHECK_CUSTOMER_PHONE_STAUTS_OPENING.equals(checkCustomerPhoneStauts)){
                DsmtCustomer customer = new DsmtCustomer();
                String accessToken = WeiXinUtils.getAccessToken(projectAppId,projectAppsecret).getAccess_token();
                //获取到微信用户的信息
                WeiXinUser userinfo = wechatService.getUserInfo(accessToken, openId);
                customer.setName(userinfo.getNickname());
                customer.setCode("未在系统内登记!");
                map.put("customer",customer);
                map.put("planList",new ArrayList());
                return map;
            }else if(ProjectConst.CHECK_CUSTOMER_PHONE_STAUTS_CLOSEING.equals(checkCustomerPhoneStauts)){
                throw new BusinessException("未在系统内登记!");
            }
        }
        if ( customerList.size() != 1) {
            throw new BusinessException("手机号码查找客户资料异常!");
        }
        DsmtCustomer customer = customerList.get(0);//暂时只支持一个手机号码对应一个客户
        Map params = Maps.newConcurrentMap();
        params.put("openId",openId);
        DsmtPublicWechat publicWechat = dsmtPublicWechatDao.selectByMap(params);
        if(!ObjectUtils.isEmpty(publicWechat)){
            publicWechat.setPhone(phone);
            dsmtPublicWechatDao.updateDsmtPublicWechat(publicWechat);
        }else {
            publicWechat=new DsmtPublicWechat();
            publicWechat.setOpenId(openId);
            publicWechat.setPhone(phone);
            dsmtPublicWechatDao.insertDsmtPublicWechat(publicWechat);
        }
        //获取客户下面所有的计划
        List planList = dsmtDistributionPlanService.selectPlanByCustomer(customer.getCode());
        //todo 需要展示微信信息
        map.put("customer",customer);
        map.put("planList",planList);
        return map;
    }
}
